/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package entidade.controller.JPA;

import entidade.controller.JPA.exceptions.IllegalOrphanException;
import entidade.controller.JPA.exceptions.NonexistentEntityException;
import entidade.controller.JPA.exceptions.RollbackFailureException;
import entidade.persistencia.Manutencao;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import entidade.persistencia.Usuario;
import entidade.persistencia.Funcionario;
import java.util.ArrayList;
import java.util.List;
import entidade.persistencia.EntradaSaida;
import entidade.persistencia.OpercaoExtra;
import entidade.persistencia.ProdutoManutencao;
import javax.transaction.UserTransaction;

/**
 *
 * @author victorinox
 */
public class ManutencaoJpaController {
    @Resource
    private UserTransaction utx = null;
    @PersistenceUnit(unitName = "globalimage2PU")
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Manutencao manutencao) throws RollbackFailureException, Exception {
        if (manutencao.getFuncionarioCollection() == null) {
            manutencao.setFuncionarioCollection(new ArrayList<Funcionario>());
        }
        if (manutencao.getEntradaSaidaCollection() == null) {
            manutencao.setEntradaSaidaCollection(new ArrayList<EntradaSaida>());
        }
        if (manutencao.getOpercaoExtraCollection() == null) {
            manutencao.setOpercaoExtraCollection(new ArrayList<OpercaoExtra>());
        }
        if (manutencao.getProdutoManutencaoCollection() == null) {
            manutencao.setProdutoManutencaoCollection(new ArrayList<ProdutoManutencao>());
        }
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Usuario clienteId = manutencao.getClienteId();
            if (clienteId != null) {
                clienteId = em.getReference(clienteId.getClass(), clienteId.getUsuarioId());
                manutencao.setClienteId(clienteId);
            }
            List<Funcionario> attachedFuncionarioCollection = new ArrayList<Funcionario>();
            for (Funcionario funcionarioCollectionFuncionarioToAttach : manutencao.getFuncionarioCollection()) {
                funcionarioCollectionFuncionarioToAttach = em.getReference(funcionarioCollectionFuncionarioToAttach.getClass(), funcionarioCollectionFuncionarioToAttach.getFuncionarioId());
                attachedFuncionarioCollection.add(funcionarioCollectionFuncionarioToAttach);
            }
            manutencao.setFuncionarioCollection(attachedFuncionarioCollection);
            List<EntradaSaida> attachedEntradaSaidaCollection = new ArrayList<EntradaSaida>();
            for (EntradaSaida entradaSaidaCollectionEntradaSaidaToAttach : manutencao.getEntradaSaidaCollection()) {
                entradaSaidaCollectionEntradaSaidaToAttach = em.getReference(entradaSaidaCollectionEntradaSaidaToAttach.getClass(), entradaSaidaCollectionEntradaSaidaToAttach.getEntradaSaidaId());
                attachedEntradaSaidaCollection.add(entradaSaidaCollectionEntradaSaidaToAttach);
            }
            manutencao.setEntradaSaidaCollection(attachedEntradaSaidaCollection);
            List<OpercaoExtra> attachedOpercaoExtraCollection = new ArrayList<OpercaoExtra>();
            for (OpercaoExtra opercaoExtraCollectionOpercaoExtraToAttach : manutencao.getOpercaoExtraCollection()) {
                opercaoExtraCollectionOpercaoExtraToAttach = em.getReference(opercaoExtraCollectionOpercaoExtraToAttach.getClass(), opercaoExtraCollectionOpercaoExtraToAttach.getOperacaoExtraId());
                attachedOpercaoExtraCollection.add(opercaoExtraCollectionOpercaoExtraToAttach);
            }
            manutencao.setOpercaoExtraCollection(attachedOpercaoExtraCollection);
            List<ProdutoManutencao> attachedProdutoManutencaoCollection = new ArrayList<ProdutoManutencao>();
            for (ProdutoManutencao produtoManutencaoCollectionProdutoManutencaoToAttach : manutencao.getProdutoManutencaoCollection()) {
                produtoManutencaoCollectionProdutoManutencaoToAttach = em.getReference(produtoManutencaoCollectionProdutoManutencaoToAttach.getClass(), produtoManutencaoCollectionProdutoManutencaoToAttach.getProdutoManutencaoPK());
                attachedProdutoManutencaoCollection.add(produtoManutencaoCollectionProdutoManutencaoToAttach);
            }
            manutencao.setProdutoManutencaoCollection(attachedProdutoManutencaoCollection);
            em.persist(manutencao);
            if (clienteId != null) {
                clienteId.getManutencaoCollection().add(manutencao);
                clienteId = em.merge(clienteId);
            }
            for (Funcionario funcionarioCollectionFuncionario : manutencao.getFuncionarioCollection()) {
                funcionarioCollectionFuncionario.getManutencaoCollection().add(manutencao);
                funcionarioCollectionFuncionario = em.merge(funcionarioCollectionFuncionario);
            }
            for (EntradaSaida entradaSaidaCollectionEntradaSaida : manutencao.getEntradaSaidaCollection()) {
                entradaSaidaCollectionEntradaSaida.getManutencaoCollection().add(manutencao);
                entradaSaidaCollectionEntradaSaida = em.merge(entradaSaidaCollectionEntradaSaida);
            }
            for (OpercaoExtra opercaoExtraCollectionOpercaoExtra : manutencao.getOpercaoExtraCollection()) {
                Manutencao oldManutencaoIdOfOpercaoExtraCollectionOpercaoExtra = opercaoExtraCollectionOpercaoExtra.getManutencaoId();
                opercaoExtraCollectionOpercaoExtra.setManutencaoId(manutencao);
                opercaoExtraCollectionOpercaoExtra = em.merge(opercaoExtraCollectionOpercaoExtra);
                if (oldManutencaoIdOfOpercaoExtraCollectionOpercaoExtra != null) {
                    oldManutencaoIdOfOpercaoExtraCollectionOpercaoExtra.getOpercaoExtraCollection().remove(opercaoExtraCollectionOpercaoExtra);
                    oldManutencaoIdOfOpercaoExtraCollectionOpercaoExtra = em.merge(oldManutencaoIdOfOpercaoExtraCollectionOpercaoExtra);
                }
            }
            for (ProdutoManutencao produtoManutencaoCollectionProdutoManutencao : manutencao.getProdutoManutencaoCollection()) {
                Manutencao oldManutencaoOfProdutoManutencaoCollectionProdutoManutencao = produtoManutencaoCollectionProdutoManutencao.getManutencao();
                produtoManutencaoCollectionProdutoManutencao.setManutencao(manutencao);
                produtoManutencaoCollectionProdutoManutencao = em.merge(produtoManutencaoCollectionProdutoManutencao);
                if (oldManutencaoOfProdutoManutencaoCollectionProdutoManutencao != null) {
                    oldManutencaoOfProdutoManutencaoCollectionProdutoManutencao.getProdutoManutencaoCollection().remove(produtoManutencaoCollectionProdutoManutencao);
                    oldManutencaoOfProdutoManutencaoCollectionProdutoManutencao = em.merge(oldManutencaoOfProdutoManutencaoCollectionProdutoManutencao);
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Manutencao manutencao) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Manutencao persistentManutencao = em.find(Manutencao.class, manutencao.getManutencaoId());
            Usuario clienteIdOld = persistentManutencao.getClienteId();
            Usuario clienteIdNew = manutencao.getClienteId();
            List<Funcionario> funcionarioCollectionOld = persistentManutencao.getFuncionarioCollection();
            List<Funcionario> funcionarioCollectionNew = manutencao.getFuncionarioCollection();
            List<EntradaSaida> entradaSaidaCollectionOld = persistentManutencao.getEntradaSaidaCollection();
            List<EntradaSaida> entradaSaidaCollectionNew = manutencao.getEntradaSaidaCollection();
            List<OpercaoExtra> opercaoExtraCollectionOld = persistentManutencao.getOpercaoExtraCollection();
            List<OpercaoExtra> opercaoExtraCollectionNew = manutencao.getOpercaoExtraCollection();
            List<ProdutoManutencao> produtoManutencaoCollectionOld = persistentManutencao.getProdutoManutencaoCollection();
            List<ProdutoManutencao> produtoManutencaoCollectionNew = manutencao.getProdutoManutencaoCollection();
            List<String> illegalOrphanMessages = null;
            for (ProdutoManutencao produtoManutencaoCollectionOldProdutoManutencao : produtoManutencaoCollectionOld) {
                if (!produtoManutencaoCollectionNew.contains(produtoManutencaoCollectionOldProdutoManutencao)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain ProdutoManutencao " + produtoManutencaoCollectionOldProdutoManutencao + " since its manutencao field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (clienteIdNew != null) {
                clienteIdNew = em.getReference(clienteIdNew.getClass(), clienteIdNew.getUsuarioId());
                manutencao.setClienteId(clienteIdNew);
            }
            List<Funcionario> attachedFuncionarioCollectionNew = new ArrayList<Funcionario>();
            for (Funcionario funcionarioCollectionNewFuncionarioToAttach : funcionarioCollectionNew) {
                funcionarioCollectionNewFuncionarioToAttach = em.getReference(funcionarioCollectionNewFuncionarioToAttach.getClass(), funcionarioCollectionNewFuncionarioToAttach.getFuncionarioId());
                attachedFuncionarioCollectionNew.add(funcionarioCollectionNewFuncionarioToAttach);
            }
            funcionarioCollectionNew = attachedFuncionarioCollectionNew;
            manutencao.setFuncionarioCollection(funcionarioCollectionNew);
            List<EntradaSaida> attachedEntradaSaidaCollectionNew = new ArrayList<EntradaSaida>();
            for (EntradaSaida entradaSaidaCollectionNewEntradaSaidaToAttach : entradaSaidaCollectionNew) {
                entradaSaidaCollectionNewEntradaSaidaToAttach = em.getReference(entradaSaidaCollectionNewEntradaSaidaToAttach.getClass(), entradaSaidaCollectionNewEntradaSaidaToAttach.getEntradaSaidaId());
                attachedEntradaSaidaCollectionNew.add(entradaSaidaCollectionNewEntradaSaidaToAttach);
            }
            entradaSaidaCollectionNew = attachedEntradaSaidaCollectionNew;
            manutencao.setEntradaSaidaCollection(entradaSaidaCollectionNew);
            List<OpercaoExtra> attachedOpercaoExtraCollectionNew = new ArrayList<OpercaoExtra>();
            for (OpercaoExtra opercaoExtraCollectionNewOpercaoExtraToAttach : opercaoExtraCollectionNew) {
                opercaoExtraCollectionNewOpercaoExtraToAttach = em.getReference(opercaoExtraCollectionNewOpercaoExtraToAttach.getClass(), opercaoExtraCollectionNewOpercaoExtraToAttach.getOperacaoExtraId());
                attachedOpercaoExtraCollectionNew.add(opercaoExtraCollectionNewOpercaoExtraToAttach);
            }
            opercaoExtraCollectionNew = attachedOpercaoExtraCollectionNew;
            manutencao.setOpercaoExtraCollection(opercaoExtraCollectionNew);
            List<ProdutoManutencao> attachedProdutoManutencaoCollectionNew = new ArrayList<ProdutoManutencao>();
            for (ProdutoManutencao produtoManutencaoCollectionNewProdutoManutencaoToAttach : produtoManutencaoCollectionNew) {
                produtoManutencaoCollectionNewProdutoManutencaoToAttach = em.getReference(produtoManutencaoCollectionNewProdutoManutencaoToAttach.getClass(), produtoManutencaoCollectionNewProdutoManutencaoToAttach.getProdutoManutencaoPK());
                attachedProdutoManutencaoCollectionNew.add(produtoManutencaoCollectionNewProdutoManutencaoToAttach);
            }
            produtoManutencaoCollectionNew = attachedProdutoManutencaoCollectionNew;
            manutencao.setProdutoManutencaoCollection(produtoManutencaoCollectionNew);
            manutencao = em.merge(manutencao);
            if (clienteIdOld != null && !clienteIdOld.equals(clienteIdNew)) {
                clienteIdOld.getManutencaoCollection().remove(manutencao);
                clienteIdOld = em.merge(clienteIdOld);
            }
            if (clienteIdNew != null && !clienteIdNew.equals(clienteIdOld)) {
                clienteIdNew.getManutencaoCollection().add(manutencao);
                clienteIdNew = em.merge(clienteIdNew);
            }
            for (Funcionario funcionarioCollectionOldFuncionario : funcionarioCollectionOld) {
                if (!funcionarioCollectionNew.contains(funcionarioCollectionOldFuncionario)) {
                    funcionarioCollectionOldFuncionario.getManutencaoCollection().remove(manutencao);
                    funcionarioCollectionOldFuncionario = em.merge(funcionarioCollectionOldFuncionario);
                }
            }
            for (Funcionario funcionarioCollectionNewFuncionario : funcionarioCollectionNew) {
                if (!funcionarioCollectionOld.contains(funcionarioCollectionNewFuncionario)) {
                    funcionarioCollectionNewFuncionario.getManutencaoCollection().add(manutencao);
                    funcionarioCollectionNewFuncionario = em.merge(funcionarioCollectionNewFuncionario);
                }
            }
            for (EntradaSaida entradaSaidaCollectionOldEntradaSaida : entradaSaidaCollectionOld) {
                if (!entradaSaidaCollectionNew.contains(entradaSaidaCollectionOldEntradaSaida)) {
                    entradaSaidaCollectionOldEntradaSaida.getManutencaoCollection().remove(manutencao);
                    entradaSaidaCollectionOldEntradaSaida = em.merge(entradaSaidaCollectionOldEntradaSaida);
                }
            }
            for (EntradaSaida entradaSaidaCollectionNewEntradaSaida : entradaSaidaCollectionNew) {
                if (!entradaSaidaCollectionOld.contains(entradaSaidaCollectionNewEntradaSaida)) {
                    entradaSaidaCollectionNewEntradaSaida.getManutencaoCollection().add(manutencao);
                    entradaSaidaCollectionNewEntradaSaida = em.merge(entradaSaidaCollectionNewEntradaSaida);
                }
            }
            for (OpercaoExtra opercaoExtraCollectionOldOpercaoExtra : opercaoExtraCollectionOld) {
                if (!opercaoExtraCollectionNew.contains(opercaoExtraCollectionOldOpercaoExtra)) {
                    opercaoExtraCollectionOldOpercaoExtra.setManutencaoId(null);
                    opercaoExtraCollectionOldOpercaoExtra = em.merge(opercaoExtraCollectionOldOpercaoExtra);
                }
            }
            for (OpercaoExtra opercaoExtraCollectionNewOpercaoExtra : opercaoExtraCollectionNew) {
                if (!opercaoExtraCollectionOld.contains(opercaoExtraCollectionNewOpercaoExtra)) {
                    Manutencao oldManutencaoIdOfOpercaoExtraCollectionNewOpercaoExtra = opercaoExtraCollectionNewOpercaoExtra.getManutencaoId();
                    opercaoExtraCollectionNewOpercaoExtra.setManutencaoId(manutencao);
                    opercaoExtraCollectionNewOpercaoExtra = em.merge(opercaoExtraCollectionNewOpercaoExtra);
                    if (oldManutencaoIdOfOpercaoExtraCollectionNewOpercaoExtra != null && !oldManutencaoIdOfOpercaoExtraCollectionNewOpercaoExtra.equals(manutencao)) {
                        oldManutencaoIdOfOpercaoExtraCollectionNewOpercaoExtra.getOpercaoExtraCollection().remove(opercaoExtraCollectionNewOpercaoExtra);
                        oldManutencaoIdOfOpercaoExtraCollectionNewOpercaoExtra = em.merge(oldManutencaoIdOfOpercaoExtraCollectionNewOpercaoExtra);
                    }
                }
            }
            for (ProdutoManutencao produtoManutencaoCollectionNewProdutoManutencao : produtoManutencaoCollectionNew) {
                if (!produtoManutencaoCollectionOld.contains(produtoManutencaoCollectionNewProdutoManutencao)) {
                    Manutencao oldManutencaoOfProdutoManutencaoCollectionNewProdutoManutencao = produtoManutencaoCollectionNewProdutoManutencao.getManutencao();
                    produtoManutencaoCollectionNewProdutoManutencao.setManutencao(manutencao);
                    produtoManutencaoCollectionNewProdutoManutencao = em.merge(produtoManutencaoCollectionNewProdutoManutencao);
                    if (oldManutencaoOfProdutoManutencaoCollectionNewProdutoManutencao != null && !oldManutencaoOfProdutoManutencaoCollectionNewProdutoManutencao.equals(manutencao)) {
                        oldManutencaoOfProdutoManutencaoCollectionNewProdutoManutencao.getProdutoManutencaoCollection().remove(produtoManutencaoCollectionNewProdutoManutencao);
                        oldManutencaoOfProdutoManutencaoCollectionNewProdutoManutencao = em.merge(oldManutencaoOfProdutoManutencaoCollectionNewProdutoManutencao);
                    }
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = manutencao.getManutencaoId();
                if (findManutencao(id) == null) {
                    throw new NonexistentEntityException("The manutencao with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Manutencao manutencao;
            try {
                manutencao = em.getReference(Manutencao.class, id);
                manutencao.getManutencaoId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The manutencao with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<ProdutoManutencao> produtoManutencaoCollectionOrphanCheck = manutencao.getProdutoManutencaoCollection();
            for (ProdutoManutencao produtoManutencaoCollectionOrphanCheckProdutoManutencao : produtoManutencaoCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Manutencao (" + manutencao + ") cannot be destroyed since the ProdutoManutencao " + produtoManutencaoCollectionOrphanCheckProdutoManutencao + " in its produtoManutencaoCollection field has a non-nullable manutencao field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Usuario clienteId = manutencao.getClienteId();
            if (clienteId != null) {
                clienteId.getManutencaoCollection().remove(manutencao);
                clienteId = em.merge(clienteId);
            }
            List<Funcionario> funcionarioCollection = manutencao.getFuncionarioCollection();
            for (Funcionario funcionarioCollectionFuncionario : funcionarioCollection) {
                funcionarioCollectionFuncionario.getManutencaoCollection().remove(manutencao);
                funcionarioCollectionFuncionario = em.merge(funcionarioCollectionFuncionario);
            }
            List<EntradaSaida> entradaSaidaCollection = manutencao.getEntradaSaidaCollection();
            for (EntradaSaida entradaSaidaCollectionEntradaSaida : entradaSaidaCollection) {
                entradaSaidaCollectionEntradaSaida.getManutencaoCollection().remove(manutencao);
                entradaSaidaCollectionEntradaSaida = em.merge(entradaSaidaCollectionEntradaSaida);
            }
            List<OpercaoExtra> opercaoExtraCollection = manutencao.getOpercaoExtraCollection();
            for (OpercaoExtra opercaoExtraCollectionOpercaoExtra : opercaoExtraCollection) {
                opercaoExtraCollectionOpercaoExtra.setManutencaoId(null);
                opercaoExtraCollectionOpercaoExtra = em.merge(opercaoExtraCollectionOpercaoExtra);
            }
            em.remove(manutencao);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Manutencao> findManutencaoEntities() {
        return findManutencaoEntities(true, -1, -1);
    }

    public List<Manutencao> findManutencaoEntities(int maxResults, int firstResult) {
        return findManutencaoEntities(false, maxResults, firstResult);
    }

    private List<Manutencao> findManutencaoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Manutencao as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Manutencao findManutencao(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Manutencao.class, id);
        } finally {
            em.close();
        }
    }

    public int getManutencaoCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) em.createQuery("select count(o) from Manutencao as o").getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
